package com.lixueju.security.box.web.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lixueju.security.box.core.enums.TableFieldEnum;
import com.lixueju.security.box.core.exception.SecurityBoxException;
import com.lixueju.security.box.core.model.AuthMenu;
import com.lixueju.security.box.core.model.AuthRole;
import com.lixueju.security.box.web.mapper.AuthRoleMapper;
import com.lixueju.security.box.core.model.AuthRoleMenuRel;
import com.lixueju.security.box.core.model.AuthUserRoleRel;
import com.lixueju.security.box.core.model.request.UpdatePermissionRequest;
import com.lixueju.security.box.web.service.IAuthMenuService;
import com.lixueju.security.box.web.service.IAuthRoleMenuRelService;
import com.lixueju.security.box.web.service.IAuthRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lixueju.security.box.web.service.IAuthUserRoleRelService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 储存角色信息 服务实现类
 * </p>
 *
 * @author lixueju
 * @since 2019-11-13
 */
@Service
public class AuthRoleServiceImpl extends ServiceImpl<AuthRoleMapper, AuthRole> implements IAuthRoleService {
    @Autowired
    private IAuthRoleMenuRelService authRoleMenuRelService;

    @Autowired
    private IAuthUserRoleRelService authUserRoleRelService;

    @Autowired
    private IAuthMenuService authMenuService;

    @Override
    public IPage<AuthRole> selectAuthRolePage(Page<AuthRole> page, AuthRole authRole) {
        QueryWrapper<AuthRole> queryAuthRole = new QueryWrapper<>();
        queryAuthRole.eq("delFlag", TableFieldEnum.AllOfdelFlag.no.code());
        if (!StringUtils.isBlank(authRole.getName())) {
            queryAuthRole.like("name", authRole.getName());
        }
        this.page(page, queryAuthRole);
        List<AuthRole> records = page.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return page;
        }
        Set<Long> roleIdSet = new HashSet<>();
        for (AuthRole record : records) {
            roleIdSet.add(record.getId());
        }
        QueryWrapper<AuthRoleMenuRel> quAuthRoleMenuRel = new QueryWrapper<>();
        quAuthRoleMenuRel.in("roleId", roleIdSet);
        List<AuthRoleMenuRel> authRoleMenuRelList = authRoleMenuRelService.list(quAuthRoleMenuRel);
        if (CollectionUtils.isEmpty(authRoleMenuRelList)) {
            return page;
        }
        Map<Long, List<AuthRoleMenuRel>> authRoleMenuRelListMap = authRoleMenuRelList.stream().collect(Collectors.groupingBy(AuthRoleMenuRel::getRoleId));
        for (AuthRole record : records) {
            List<AuthRoleMenuRel> authRoleMenuRels = authRoleMenuRelListMap.get(record.getId());
            if (CollectionUtils.isEmpty(authRoleMenuRels)) {
                continue;
            }
            JSONObject extend = record.getExtend();
            JSONArray menuOperationIds = new JSONArray();
            for (AuthRoleMenuRel rel : authRoleMenuRels) {
                menuOperationIds.add(rel.getMenuId() + "");
            }
            extend.put("menuOperationIds", menuOperationIds);
        }
        return page;
    }

    @Override
    public Boolean updatePermission(UpdatePermissionRequest updatePermissionRequest) {
        if (updatePermissionRequest.getRoleId() == null) {
            throw new SecurityBoxException("角色Id不可为空");
        }
        QueryWrapper<AuthRoleMenuRel> delAuthRoleMenuRel = new QueryWrapper<>();
        delAuthRoleMenuRel.eq("roleId", updatePermissionRequest.getRoleId());
        authRoleMenuRelService.remove(delAuthRoleMenuRel);
        Set<Long> operationMenuIds = updatePermissionRequest.getMenuIds();
        if (operationMenuIds == null || operationMenuIds.size() < 1) {
            return true;
        }
        List<AuthMenu> authMenuList = authMenuService.getAuthMenuListByChildrenIds(null, operationMenuIds);
        if (authMenuList == null || authMenuList.size() < 1) {
            return true;
        }
        List<AuthRoleMenuRel> newList = new ArrayList<>();
        for (AuthMenu authMenu : authMenuList) {
            AuthRoleMenuRel authRoleMenuRel = new AuthRoleMenuRel();
            authRoleMenuRel.setMenuId(authMenu.getId());
            authRoleMenuRel.setRoleId(updatePermissionRequest.getRoleId());
            newList.add(authRoleMenuRel);
        }
        if (newList.size() > 0) {
            authRoleMenuRelService.saveBatch(newList);
        }
        return true;
    }

    @Override
    public Boolean deleteAuthRole(AuthRole authRole) {
        if (authRole.getId() == null) {
            throw new SecurityBoxException("角色Id不可为空");
        }
        QueryWrapper<AuthRoleMenuRel> delAuthRoleMenuRel = new QueryWrapper<>();
        delAuthRoleMenuRel.eq("roleId", authRole.getId());
        authRoleMenuRelService.remove(delAuthRoleMenuRel);

        QueryWrapper<AuthUserRoleRel> delAuthUserRoleRel = new QueryWrapper<>();
        delAuthUserRoleRel.eq("roleId", authRole.getId());
        authUserRoleRelService.remove(delAuthUserRoleRel);

        return this.removeById(authRole.getId());
    }
}
